Previous Book Contents Book Index Next

Inside Macintosh: QuickDraw GX Objects /
Chapter 7 - View-Related Objects / Using View-Related Objects


Using View Groups

This section demonstrates how to use QuickDraw GX view groups. It shows how you can

Creating and Manipulating View Group Objects

QuickDraw GX provides the GXNewViewGroup function to allow you to create a new view group object, and the GXDisposeViewGroup function to delete it. Normally, you create a view group only for the purpose of offscreen drawing.

Listing 7-13 is a continuation of the routine in Listing 7-12 on page 7-58 that sets up a data structure for offscreen drawing through a given view port. This part of the code fills in various fields of the buffers data structure and calls GXNewViewGroup to create an offscreen view group. In addition, it calls GXNewViewPort to create an offscreen view port (slavePort) in the new group, and GXGetShapeGlobalViewDevices to copy all drawable devices from the original onscreen view port (port) into a list in the data structure.

Listing 7-13 Setting up a data structure for offscreen drawing

.
.  /* continued from Listing 7-12 on page 7-58 */
.
   buffersHandle = (viewPortBuffer) NewHandle(sizeof
                     (viewPortBufferRecord) + (deviceCount - 1) * 
                     sizeof(gxViewDevice));

   NilParamReturnNil(port);      /* error-check the handle */
   HLock((Handle) buffersHandle);
   buffers = *buffersHandle;
   buffers->group = GXNewViewGroup();
   buffers->masterPort = port;
   buffers->slavePort = GXNewViewPort(buffers->group);
   buffers->area = area;
   buffers->draw = GXNewShape(gxPictureType);
   buffers->deviceCount = deviceCount;
   GXSetViewPortDither(buffers->slavePort, 
                        GXGetViewPortDither(port));
   GXGetShapeGlobalViewDevices(area, port, buffers->devices);
Once you have created a view group object, you can assign view ports and view
devices to it with the GXSetViewPortViewGroup function (as described under "Manipulating View Port Object Properties" beginning on page 7-42) and the GXSetViewDeviceViewGroup function (as described under "Manipulating View Device Object Properties" beginning on page 7-54).

At any time, you can retrieve a list of view ports or view devices that belong
to a view group by calling the functions GXGetViewGroupViewPorts and GXGetViewGroupViewDevices. See Listing 7-2 on page 7-44 for an example of the
use of GXGetViewGroupViewPorts; see Listing 7-10 on page 7-54 for an example of the use of GXGetViewGroupViewDevices.

When you have finished using an offscreen view group, you delete it with the GXDisposeViewGroup function. For an example of the use of GXDisposeViewGroup, see page 7-63.

The GXNewViewGroup function is described on page 7-122. The GXDisposeViewGroup function is described on page 7-122.

The GXGetViewGroupViewPorts function is described on page 7-123. The GXGetViewGroupViewDevices function is described on page 7-124.

Setting Up an Offscreen View Group

This section shows how to set up a view port for offscreen drawing. Examples of most of the steps shown here have already been presented elsewhere in this chapter, although not all together.

Offscreen drawing requires creating a new view group, so that drawing does not conflict with the screen devices view group. You must also create a view port to draw into. To set up the view port, you must create a view device object; however, for offscreen drawing the view device object need not correspond to any physical device. Follow this typical sequence of steps to set up an offscreen view group:

  1. Create a new view group.
  2. Create a new view device in this view group, specifying a bit map that represents the area that you may want to copy onscreen later.
  3. Create a new view port in this view group.
  4. Retrieve the bitmap as a shape object of its own, so that you can later draw it directly onscreen.
  5. Create a transform object for your shapes, and assign the view port to its view port list.

Listing 7-14 is a partial example of a routine that sets up an offscreen drawing environment. It does not show how the bitmap shape (bitShape) for the device is set up. See the bitmap shapes chapter of Inside Macintosh: QuickDraw GX Graphics for information on bitmap shapes.

Listing 7-14 Setting up a view port and view group for offscreen drawing

gxShape        myDraw, bitShape;
gxTransform    myXform;
gxViewDevice   myDevice;
gxViewPort     myPort;
gxViewGroup    myGroup;
.
.  /* set up bitmap shape for offscreen view device */
.
myGroup = GXNewViewGroup();
myDevice = GXNewViewDevice(myGroup, bitShape);
myPort = GXNewViewPort(myGroup);
myDraw = GXGetViewDeviceBitmap(myDevice);
myXform = GXNewTransform();
GXSetTransformViewPorts(myXform, 1, &myPort);
The myDraw shape represents your offscreen drawing buffer. Whenever you draw a shape that has myXform as its transform object, drawing takes place offscreen, in the pixel image associated with myDraw. If you added a view port in the onscreen view group to the view port list of myXform, drawing could take place both offscreen and onscreen simultaneously.

It is useful to have a direct reference to myDraw because you can draw it itself, which would have the effect of transferring the offscreen buffer onto the screen (if myDraw references a transform object that references onscreen view ports).

When you are finished with offscreen drawing, you can dispose of the objects you have created:

GXDisposeShape(myDraw);
GXDisposeTransform(myXform);
GXDisposeViewGroup(myGroup);
You do not have to explicitly dispose of your offscreen view port or view device, because calling GXDisposeViewGroup causes QuickDraw GX to dispose of all of its view ports and view devices.

Measuring a Shape in Global Space

The GXGetShapeGlobalBounds function measures the bounding rectangle of a shape in global coordinates--that is, after the transform mapping has been applied to the shape geometry, and after all view port mappings have been applied. You can thus use GXGetShapeGlobalBounds to compare the true positions and sizes of any two shapes in the same view group, even if they do not share the same view port or do not appear on the same view device. (To compare the positions and sizes of two shapes in the same view port, you can use the GXGetShapeLocalBounds function; to measure a shape on a view device, use GXGetShapeDeviceBounds.)

Listing 7-15 is a library function used in offscreen drawing. The function returns the device characteristics (a bitmap structure plus an offset) of a particular "area," the intersection of an offscreen view device and an offscreen view port. Area-characteristics structures are used by this library to store device-specific drawing information for each area within the offscreen view port occupied by the pixel image of a device. This listing uses GXGetShapeGlobalBounds to determine the intersection of the specified shape (area) with the specified view device (device), which determines the size of the image stored in the area-characteristics structure (x).

Listing 7-15 Returning the characteristics of an offscreen device area

static areaCharacteristics GetAreaCharacteristics(gxShape area, 
                                             gxViewDevice device, 
                                             gxViewPort port)
{
   areaCharacteristics x;  /* a bitmap structure & location */
   gxRectangle bounds;
   gxShape bitShape;
   gxMapping map;
.
.
.  /* get device bitmap and shape bounds on device */
   bitShape = GXGetViewDeviceBitmap(device);
   GXGetShapeGlobalBounds(area, port, nil, &bounds);

   /* fill out the area-characteristics structure */
   GXGetBitmap(bitShape, &x.bits, nil);
   if (x.bits.space == gxIndexedSpace)
      GXCloneColorSet(x.bits.set);
   if (x.bits.profile)
      GXCloneColorProfile(x.bits.profile);
   GXDisposeShape(bitShape);
   x.offset.x = bounds.left;
   x.offset.y = bounds.top;
   x.bits.width = FixedRound(bounds.right) - 
                                       FixedRound(bounds.left);
   x.bits.height = FixedRound(bounds.bottom) - 
                                       FixedRound(bounds.top);

   /* map the area offset back to local space, store in x */
   InvertMapping(&map, GXGetViewPortGlobalMapping(port, &map));
   MapPoints(&map, 1, &x.offset);
   return x;
}
The GXGetShapeGlobalBounds function is described on page 7-125.

The GXGetShapeLocalBounds function is described on page 7-96. The GXGetShapeDeviceBounds function is described on page 7-116.


Previous Book Contents Book Index Next

© Apple Computer, Inc.
7 JUL 1996